﻿using System;
using Magellan.Abstractions;
using Magellan.Framework;
using Magellan.Routing;

namespace Magellan
{
    /// <summary>
    /// Navigators provide navigation services for a specific frame of navigation. They are created using 
    /// the <see cref="NavigatorFactory"/>.
    /// </summary>
    public interface INavigator : INavigationService
    {
        /// <summary>
        /// Gets the <see cref="INavigatorFactory"/> that produced this <see cref="INavigator"/>.
        /// </summary>
        /// <value>The factory.</value>
        INavigatorFactory Factory { get; }

        /// <summary>
        /// Gets a collection of registered progress observers.
        /// </summary>
        /// <value>The progress listeners.</value>
        NavigationProgressListenerCollection ProgressListeners { get; }

        /// <summary>
        /// Navigates to the specified URI, resolving the first matching route.
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        void Navigate(string requestUri);

        /// <summary>
        /// Navigates to the specified URI, resolving the first matching route.
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        void Navigate(Uri requestUri);

        /// <summary>
        /// Navigates to the specified URI, resolving the first matching route.
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        /// <param name="additionalData">Additional data (like post data) that is not in the URI but is used
        /// for navigation.</param>
        void Navigate(Uri requestUri, object additionalData);

        /// <summary>
        /// Navigates to the specified URI, resolving the first matching route.
        /// </summary>
        /// <param name="requestUri">The request URI.</param>
        /// <param name="additionalData">Additional data (like post data) that is not in the URI but is used 
        /// for navigation.</param>
        void Navigate(Uri requestUri, RouteValueDictionary additionalData);

        /// <summary>
        /// Resolves and navigates to the first route that matches the given set of route values.
        /// </summary>
        /// <param name="routeValues">
        /// The route values. For example, <code>new { controller = "MyController", action = "MyAction" }</code>
        /// </param>
        void Navigate(object routeValues);

        /// <summary>
        /// Resolves and navigates to the first route that matches the given set of route values.
        /// </summary>
        /// <param name="request">The request.</param>
        void Navigate(RouteValueDictionary request);
    }
}